//
//  Calc.swift
//  KoiAccounting
//
//  Created by 纪洪文 on 27.03.25.
//

import Foundation
class Calc : ObservableObject{
    
    var formulaContent = String()
    
    func input(text: String) {
        // 判断输入是否是数字
        if (!checkInput(input: text)) {
            return
        }
        if (text == "." && ((formulaContent.isEmpty) || formulaContent.last?.isNumber == false)) {
            formulaContent.append("0.")
        } else {
            formulaContent.append(text)
        }
    }
    
    func calc() -> String {
        let result = Formula().calc(formulaContent:formulaContent)
        formulaContent.removeAll()
        formulaContent.append(result)
        return result
    }
    
    func backspace() {
        if (!formulaContent.isEmpty) {
            formulaContent.removeLast()
        }
    }
    
    func reset() {
        formulaContent.removeAll()
    }
    
    func hasSymbol() -> Bool {
        return Symbol.match(input: formulaContent)
    }
    
    func checkInput(input: String) -> Bool{
        if (formulaContent.isEmpty) {
            // 如果公式内容为空，代表刚开始输入，允许输入
            return true
        }
        let strArr = formulaContent.split(separator: Symbol.opPattern)
        let lastNumber = strArr.last
        // 如果最后一个是 empty ，那么应该最后一位是 + 或 - 这样不可以再输入 + | -
        if (Symbol.isOperator(char: formulaContent.last)) {
            // 检测到输入的 + | - 不合法 其他字符都合法
            return !Symbol.match(input: input)
        } else {
            // 最后一位不是空，可以执行数字检测逻辑
            if (Symbol.match(input: input)) {
                // 在数字后输入 + - 是可以的
                return true
            } else if (input == ".") {
                // 如果输入的是 . ，最后一个数字不能是小数，可以通过是否包含 . 简单判断
                return lastNumber?.contains(".") == false
            } else {
                if (lastNumber == "0") {
                    // 如果最后一个数字是 0 ，输入数字后，前边的 0 去掉
                    formulaContent.removeLast()
                    return true
                } else {
                    // 如果 lastNumber 加上 input 还是一个数字
                    // 执行一下数字长度限制
                    if (Calc.isValid((lastNumber! + input))) {
                        // 长度限制
                        return !lengthLimitOne(s:(lastNumber! + input))
                    } else {
                        return false
                    }
                }
            }
        }
    }
    
    private func lengthLimitOne(s: String) -> Bool {
        let sArr = s.split(separator: ".")
        if (sArr.count == 1) {
            return sArr[0].count > 8
        } else {
            return sArr[0].count > 8 || sArr[1].count > 2
        }
    }
    
    static let numberPattern = /^\d+(\.\d+)$|^[1-9]\d*$/
    
    static func isValid(_ input: String) -> Bool {
        return (try? numberPattern.wholeMatch(in: input)) != nil
    }
}
